# -*-coding:utf-8-*-

import time

from bson.objectid import ObjectId
import pymongo
from tornado.gen import coroutine, Return

from daos.base_async import BaseDao, BaseRecord

Transfers_Document_Structure = {
    '_id': 'TRANSFER_ID',
    'uid': 'USER_ID',  # user_id
    'vid': 'VENDOR_ID',  # vendor_id
    'created_time': 123,
    'done_time': 123,
    'status': 'applying | refused | done',
    'refuse_reason': 'reason',
    'amount': 123.45,
    'desc': 'description of this transfer',
    'transfer_from': 'commission | reward',  # default account
    'transfer_to': 'wx | ali | debit_card | credit_card | ...',
    'transfer_through': 'aliinpay | wx | manual',
    'transfer_res': {
        'wx': {},
        'ali': {},
        'allinpay': {},
    },
    'specifics': {
        'alinpay': {
            'account_no': 'ACCOUNT_NO',
            'account_name': 'ACCOUNT_NAME',
        },
        'amount_detail': {
            'commission_as_s': 10,
            'commission_as_ss': 10,
            'commission_as_ts': 10,
        }
    },
}


class Transfer(BaseRecord):
    def __getattr__(self, item):
        if 'allinpay_account_no' == item:
            args = ('specifics', 'allinpay', 'account_no')
        elif 'allinpay_account_name' == item:
            args = ('specifics', 'allinpay', 'account_name')
        else:
            args = (item,)
        return self._get_optional_field(*args)


class TransfersDao(BaseDao):
    def __init__(self, db):
        super(TransfersDao, self).__init__(db, 'transfers')

    def _get_record_object(self, data):
        return Transfer(data)

    # TODO: to be deleted
    def get_latest_transfer_of_user(self, uid):
        filter_cond = {'uid': uid}
        result = self.find(filter_cond).limit(1).sort('_id', pymongo.DESCENDING)
        if 0 == result.count():
            return None
        else:
            Transfer(result[0])

    @coroutine
    def create_transfer(self, uid, vid, data):
        optional_fields=['amount', 'desc', 'transfer_from', 'transfer_through', 'transfer_to', 'specifics']
        data = self.extract_fields(data, optional_fields=optional_fields)
        data['uid'] = uid
        data['vid'] = vid
        data['created_time'] = int(time.time())
        data['status'] = 'applying'
        data['transfer_from'] = data.get('transfer_from', 'commission')
        # data['transfer_to'] = data.get('transfer_to', 'debit_card')
        data['transfer_through'] = data.get('transfer_through', 'allinpay')
        r = yield self.insert_one(data)
        raise Return({'transfer_id': str(r.inserted_id)})

    @coroutine
    def delete_transfer(self, uid, tid):
        filter_cond = {'uid': uid, '_id': ObjectId(tid)}
        transfer = yield self.find_one(filter_cond)
        if 'applying' != transfer['status']:
            raise Exception('illegal status(%s)' % transfer['status'])
        r = yield self.delete_one(filter_cond)
        raise Return(1 == r.deleted_count)

    @coroutine
    def update_transfer_status(self, uid, tid, status, data, transfer_through):
        update = {
            'status': status,
            'transfer_res': {
                transfer_through: data,
            }
        }
        filter_cond = {'vid': uid, '_id': ObjectId(tid)}  # vid
        r = yield self.update_one(filter_cond, {'$set': update})
        raise Return(1 == r.matched_count)
